package com.captjack.micro.task.configuration.elasticjob;

import com.captjack.micro.task.job.SimpleJobSupport;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.sql.DataSource;

/**
 * @author Capt Jack
 * @date 2018/7/2
 */
@Configuration
@Order(value = 0)
public class ElasticJobAutoScanConfiguration implements BeanFactoryPostProcessor {

    /**
     * 日志
     */
    private static final Logger logger = LoggerFactory.getLogger(ElasticJobAutoScanConfiguration.class);

    /**
     *
     */
    private static final String ALL_JOB_PREFIX = "elastic-job-customize-";

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        try {
            // 获取容器所有包含指定注解的bean
            String[] beanNames = configurableListableBeanFactory.getBeanNamesForType(SimpleJobSupport.class);
            // zookeeper注册中心
            ZookeeperRegistryCenter zookeeperRegistryCenter = configurableListableBeanFactory.getBean("elasticJobRegisterCenter", ZookeeperRegistryCenter.class);
            // 数据源
            DataSource dataSource = configurableListableBeanFactory.getBean(("mysqlDataSource"), DataSource.class);
            // 将作业运行的痕迹进行持久化到DB
            JobEventConfiguration jobEventConfiguration = new JobEventRdbConfiguration(dataSource);
            // json解析
            Gson gson = new Gson();
            // 遍历处理
            for (String beanName : beanNames) {
                SimpleJobSupport bean = configurableListableBeanFactory.getBean(beanName, SimpleJobSupport.class);
                // 反射获取类对象
                Class<?> clazz = bean.getClass();
                // 获取作业配置
                LiteJobConfiguration liteJobConfiguration = bean.getLiteJobConfiguration();
                // 构建JobScheduler
                BeanDefinitionBuilder springJobSchedulerBuilder = BeanDefinitionBuilder.rootBeanDefinition(SpringJobScheduler.class)
                        .addConstructorArgValue(bean)
                        .addConstructorArgValue(zookeeperRegistryCenter)
                        .addConstructorArgValue(liteJobConfiguration)
                        .addConstructorArgValue(jobEventConfiguration)
                        .addConstructorArgValue(new ElasticJobListener() {
                            @Override
                            public void beforeJobExecuted(ShardingContexts shardingContexts) {
                                logger.info("beforeJobExecuted, shard-index:" + shardingContexts.getJobName() + ",time:" + System.currentTimeMillis());
                            }

                            @Override
                            public void afterJobExecuted(ShardingContexts shardingContexts) {
                                logger.info("afterJobExecuted, shard-index:" + shardingContexts.getJobName() + ",time:" + System.currentTimeMillis());
                            }
                        })
                        .setInitMethodName("init");
                // 注册bean，暴露hessian服务
                ((BeanDefinitionRegistry) configurableListableBeanFactory).registerBeanDefinition(
                        ALL_JOB_PREFIX + beanName, springJobSchedulerBuilder.getBeanDefinition());
                // hessian暴露日志
                System.out.println("register job success! className:" + clazz.getName() + ",desc:" + gson.toJson(liteJobConfiguration));
            }
            System.out.println("register all job success！count: " + beanNames.length);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("export hessian service failed, exit！");
            System.exit(0);
        }
    }

}
